package com.tanhua.server.service;

import com.alibaba.fastjson.JSON;
import com.tanhua.commons.SmsTemplate;
import com.tanhua.commons.TanHuaException;
import com.tanhua.commons.templates.FaceTemplate;
import com.tanhua.commons.templates.HuanXinTemplate;
import com.tanhua.commons.templates.OssTemplate;
import com.tanhua.domain.db.User;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.RecommendUser;
import com.tanhua.domain.vo.*;
import com.tanhua.dubbo.api.UserApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.server.utils.GetAgeUtil;
import com.tanhua.server.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class UserService {
    @Reference
    private UserApi userApi;
    @Reference
    private UserInfoApi userInfoApi;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private SmsTemplate smsTemplate;
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private FaceTemplate faceTemplate;
    @Autowired
    private OssTemplate ossTemplate;
    @Value("${tanhua.redisValidateCodeKeyPrefix}")
    private String redisValidateCodeKeyPrefix;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    public long saveUser(User user) {
        return userApi.save(user);
    }

    public User findUser(String phone) {
        return userApi.findByMobile(phone);
    }

    public void sendValidateCode(String phone) {
        String key = redisValidateCodeKeyPrefix + phone;
        //获取验证码
        String codeInRedis = stringRedisTemplate.opsForValue().get(key);
        log.info("codeInRedis:{},{}", codeInRedis, phone);
        //查询验证码
        if (null != codeInRedis) {
            throw new TanHuaException(ErrorResult.duplicate());
        } else {
            //随机验证码
            //String validateCode = RandomStringUtils.randomNumeric(6);
            String validateCode = "123456";
            //   Map<String, String> sendResult = smsTemplate.sendValidateCode(phone, validateCode);

            //如果为返回不为空发送失败
            //    if (null != sendResult) {
            if (false) {
                throw new TanHuaException(ErrorResult.fail());
            }
            log.info("发送验证成功:{},{}", phone, validateCode);
            stringRedisTemplate.opsForValue().set(key, validateCode, 10, TimeUnit.MINUTES);
        }

    }

    public Map<String, Object> loginVerification(String phone, String verificationCode) {
        String type="0102";
        //通过手机号生成验证码
        String key = redisValidateCodeKeyPrefix + phone;
        //通过手机号从redis查询验证码
        String codeInRedis = stringRedisTemplate.opsForValue().get(key);
        log.info("codeInRedis:{},{}", codeInRedis, phone);
        //如果不存在验证码说明验证码已经失效重新申请验证码
        if (null == codeInRedis) {
            throw new TanHuaException(ErrorResult.loginError());

        } else {
            //如果存在验证码就开始校验
            if (!StringUtils.isEquals(codeInRedis, verificationCode)) {
                throw new TanHuaException(ErrorResult.validateCodeError());
            } else {
                boolean isNew = false;
                //删除key
                stringRedisTemplate.delete(key);
                //查询数据库看用户是否存在存在
                User user = userApi.findByMobile(phone);
                //不存在注册为新用户
                if (null == user) {
                    type="0101";
                    user = new User();
                    user.setMobile(phone);
                    user.setPassword(DigestUtils.md2Hex(phone.substring(5)));
                    Long userId = userApi.save(user);
                    user.setId(userId);
                    //修改注册状态
                    isNew = true;
                    huanXinTemplate.register(userId);
                }
                //生成token
                String tocken = jwtUtils.creatScJWT(phone, user.getId());
                //把用户信息转换成jesion
                String userToJeson = JSON.toJSONString(user);
                String tockenKey = "TOKEN_" + tocken;
                stringRedisTemplate.opsForValue().set(tockenKey, userToJeson, 7, TimeUnit.DAYS);
                //构建返回的数据
                Map<String, Object> result = new HashMap<>();
                result.put("token", tockenKey);
                result.put("isNew", isNew);
              /*  //发送mq消息
                Map<String,Object> logMap=new HashMap<>();
                logMap.put("userId",user.getId());
                logMap.put("type",type);
                logMap.put("log_time", DateFormatUtils.format(new Date(),"yyyy-MM-dd"));
                logMap.put("place","深圳黑马");
                logMap.put("equipment","iphone 13");
                //转成json字符串
                String jsonString = JSON.toJSONString(logMap);
                log.info("log:"+jsonString);
                rocketMQTemplate.convertAndSend("tanhua_log",jsonString);*/
                return result;
            }
        }

    }

    public void loginReginfo(UserInfoVo userInfoVo, String token) {
        User loginUser = UserHolder.getUser();
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(userInfoVo, userInfo);
        userInfo.setId(UserHolder.getUserId());
        //设置年龄
        int age = GetAgeUtil.getAge(userInfo.getBirthday());
        userInfo.setAge(age);
        userInfoApi.add(userInfo);
    }

    public void uploadAvatar(MultipartFile multipartFile, String tocken) {
        try {
            User loginUser = UserHolder.getUser();
            //调百度云人脸识别
            //  boolean detect = faceTemplate.detect((multipartFile.getBytes()));
            boolean detect = true;
            System.out.println("=========" + detect + "=========");
            if (!detect) {
                //如果验证不通过
                throw new TanHuaException("人脸识别失败");
            }
            //上传图片到阿里云
            String imgUrl = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            UserInfo userInfo = new UserInfo();
            userInfo.setId(UserHolder.getUserId());
            userInfo.setAvatar(imgUrl);
            userInfoApi.update(userInfo);
        } catch (IOException e) {
            e.printStackTrace();
            throw new TanHuaException("图像上传失败");
        }
    }

    public UserInfoVo getLoginUserInfo(String token) {
        User loginUser = UserHolder.getUser();
        UserInfo userInfo = userInfoApi.findUserById(UserHolder.getUserId());
        //将userinfo转换成userInfoVo
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtils.copyProperties(userInfo, userInfoVo);
        userInfoVo.setAge(userInfo.getAge().toString());
        return userInfoVo;
    }

    public void updateLogeinUserInfo(String tocken, UserInfoVo userInfoVo) {
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(userInfoVo, userInfo);
        //设置年龄
        int age = GetAgeUtil.getAge(userInfoVo.getBirthday());
        userInfo.setAge(age);
        userInfo.setId(UserHolder.getUserId());
        userInfoApi.update(userInfo);
    }

    public void deleteLoginUserAvatar(String tocken) {
        User loginUser = UserHolder.getUser();
        UserInfo userinfo = userInfoApi.findUserById(UserHolder.getUserId());
        String avatar = userinfo.getAvatar();
        ossTemplate.deleteFile(avatar);
    }

    public CountsVo counts() {
        Long longInUserId = UserHolder.getUserId();
        Long eachLoveCount = userInfoApi.findLoveAndFan(longInUserId);
        Long loveCount = userInfoApi.findLove(longInUserId);
        Long fanCount = userInfoApi.findFan(longInUserId);
        CountsVo countsVo = new CountsVo();
        countsVo.setEachLoveCount(eachLoveCount.longValue());
        countsVo.setLoveCount(loveCount.longValue());
        countsVo.setFanCount(fanCount.longValue());
        return countsVo;
    }

    public PageResult<FriendVo> queryUserLikeList(int type, Long page, Long pagesize, String nickname) {
        Long longInUserId = UserHolder.getUserId();
        PageResult pageResult = null;
        boolean alreadyLove=false;
        switch (type) {
            case 1:
                pageResult = userInfoApi.findEachAttention(longInUserId, page, pagesize);
                alreadyLove=true;
                break;
            case 2:
                pageResult = userInfoApi.findPggeLove(longInUserId, page, pagesize);
                alreadyLove=true;
                break;
            case 3:
                pageResult = userInfoApi.findPageFans(longInUserId, page, pagesize);
                break;
            case 4:
                pageResult = userInfoApi.findPageLook(longInUserId, page, pagesize);
                break;
            default:pageResult=new PageResult();
        }
        List<RecommendUser> items = pageResult.getItems();
        List<FriendVo> friendVoList=new ArrayList<>();
        if (!CollectionUtils.isEmpty(items)){
            List<Long> recommentIdList = items.stream().map(RecommendUser::getUserId).collect(Collectors.toList());
            List<UserInfo> userInfoList = userInfoApi.findByBatchIds(recommentIdList);
            Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getId, u -> u));
            for (RecommendUser item : items) {
                FriendVo vo = new FriendVo();
                UserInfo userInfo = userInfoMap.get(item.getUserId());
                BeanUtils.copyProperties(userInfo, vo);
                vo.setMatchRate(item.getScore().intValue());
                vo.setAlreadyLove(alreadyLove);
                friendVoList.add(vo);
            }
        }
        pageResult.setItems(friendVoList);
        return pageResult;
    }

    public void likeFences(Long likeId) {
      Boolean likeFences=  userInfoApi.likeFences(UserHolder.getUserId(),likeId);
        if (likeFences){
        huanXinTemplate.makeFriends(UserHolder.getUserId(),likeId);
        }
    }
}
